﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Newtonsoft.Json.Linq;
using xbmc_json_async.System;

namespace xbmc_json_async.JSONRPC
{
    public class XJsonRpc
    {
        /* http://wiki.xbmc.org/index.php?title=JSON-RPC_API/v4#JSONRPC
         * JSONRPC.Introspect (Implemented)
         * JSONRPC.NotifyAll (Implemented)
         * JSONRPC.Permission (Not Implemented)
         * JSONRPC.Ping (Implemented)
         * JSONRPC.Version (Not Implemented)
         */
        private XClient mClient;
        private XError mError;

        public XJsonRpc(XClient client)
        {
            mClient = client;
        }

        /// <summary>
        /// Introspects returns the full json schema. 
        /// </summary>
        /// <param name="userCallback">The user callback.</param>
        public void Introspect(XDataReceived userCallback)
        {

            //var args = new JObject { new JProperty("volume", message), new JProperty("level", level.ToString()) };
            mClient.GetData("JSONRPC.Introspect", null, IntrospectCallback, userCallback);
        }

        /// <summary>
        /// Introspects the callback.
        /// </summary>
        /// <param name="requestState">State of the request.</param>
        private void IntrospectCallback(XRequestState requestState)
        {
            JObject query = JObject.Parse(requestState.ResponseData);
            if (XHelpers.CheckResponseForError(query, out mError))
            {
                //need exception handling in here
            }
            {
                if (requestState.UserCallback != null)
                {
                    requestState.UserCallback(query);
                }
            }
        }
        
        /// <summary>
        /// Notifies the specified sender.
        /// Callback not really required...?
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="message">The message.</param>
        /// <param name="userCallback">The user callback.</param>
        public void NotifyAll(string sender, string message, XDataReceived userCallback)
        {
            var args = new JObject { new JProperty("sender", sender), new JProperty("message", message) };
            mClient.GetData("JSONRPC.NotifyAll", args, NotifyCallback, userCallback);
        }
        
        /// <summary>
        /// Notifies the callback.
        /// </summary>
        /// <param name="requestState">State of the request.</param>
        private void NotifyCallback(XRequestState requestState)
        {
            JObject query = JObject.Parse(requestState.ResponseData);

            if (XHelpers.CheckResponseForError(query, out mError))
            {
                //need exception handling in here
            }
            {
                var result = (JValue)query["result"];
                if (requestState.UserCallback != null)
                {
                    requestState.UserCallback(result.ToString());
                }
            }
        }

        public void Ping(XDataReceived userCallback)
        {
            mClient.GetData("JSONRPC.Ping", null, PingCallback, userCallback);
        }
        
        private void PingCallback(XRequestState requestState)
        {
            JObject query = JObject.Parse(requestState.ResponseData);
            if (XHelpers.CheckResponseForError(query, out mError))
            {
                //need exception handling in here
            }
            {
                if (requestState.UserCallback != null)
                {
                    requestState.UserCallback(query);
                }
            }
        }
    }
}
